/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cn.icanci.snowstack.event;

import cn.icanci.snowstack.factory.SendEventFactory;
import cn.icanci.snowstack.state.RegStatusEnum;
import cn.icanci.snowstack.listener.AbstractEventListener;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * 事件源
 * 
 * @author icanci
 * @date Created in 2021/05/24 11:56
 * @version 1.0
 */
public class EventSourceObject {
    /**
     * 状态
     */
    private RegStatusEnum              status;
    /**
     * 监听器容器
     */
    private Set<AbstractEventListener> listener;

    public EventSourceObject() {
        this.listener = new HashSet<>();
        this.status = RegStatusEnum.UNCONNECTED;
    }

    /**
     * 给事件源注册监听器
     * @param cel 监听器
     */
    public void addCusListener(AbstractEventListener cel) {
        this.listener.add(cel);
    }

    /**
     * 当事件发生时,通知注册在该事件源上的所有监听器做出相应的反应（调用回调方法）
     */
    protected void notifies() {
        AbstractEventListener cel = null;
        Iterator<AbstractEventListener> iterator = this.listener.iterator();
        while (iterator.hasNext()) {
            cel = iterator.next();
            cel.execute(new CusEvent(this));
        }
    }

    public RegStatusEnum getStatus() {
        return status;
    }

    /**
     * 模拟事件触发器，当成员变量 status 的值发生变化时，触发事件。
     * @param status 传入的状态
     */
    public void setStatus(RegStatusEnum status) {
        if (this.status != status) {
            this.status = status;
            notifies();
        }
    }

    /**
     * 发事件
     * @param event 事件
     */
    public void sendEvent(RegEventEnum event) {
        SendEventFactory.targetEvent(event).executeStatus(this);
    }
}
